<!--
 * @Author: 杨光辉(GerhardYang)
 * @Date: 2021-04-02 16:37:01
 * @LastEditors: 予程_hepch
 * @LastEditTime: 2022-04-13 14:16:33
 * @Description: file content
 * @Copyright: 超图软件华中平台客户中心 (SuperMap Software Co., Ltd. -Central China Platform)
-->
<template>
  <div>
    <!-- 图层树 -->

    <a-tree
      class="layerstree"
      v-if="hackReset"
      ref="layerstree"
      size="small"
      :multiple="false"
      :checkable="true"
      :showLine="true"
      :selectable="false"
      :checkStrictly="true"
      :expanded-keys="expandedKeys"
      :auto-expand-parent="autoExpandParent"
      :tree-data="treedata"
      :load-data="onLoadData"
      :checkedKeys="checkedKeys"
      @load="onLoadnode"
      @expand="onExpand"
      @check="onCheck"
    >
      <!-- 自定义图标模板 -->
      <template slot="custom" slot-scope="item">
        <icon-font
          :type="'icon-' + item.icon"
          style="font-size: 17px; color: #1890fe"
        />
        <span>&nbsp;&nbsp;{{ item.title }}</span>
      </template>
    </a-tree>

    <!-- 空间搜索工具栏 -->
    <SpatialQueryBar
      ref="SpatialQueryBar"
      :checkedKeys="checkedKeys"
      class="SpatialQueryBar"
    />
    <!-- 结果面板 -->
    <TreeSearchResult ref="TreeSearchResult" />
  </div>
</template>
<script>
import localStorage from "@/utils/localStorage";
import "axios";
import L from "leaflet";
import { buffer, lineString } from "@turf/turf";
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
// 解决默认图标丢失问题
let DefaultIcon = L.icon({
  iconUrl: icon,
  shadowUrl: iconShadow,
  iconSize: [30, 50],
  iconAnchor: [15, 50],
  popupAnchor: [-1, -50],
});
L.Marker.prototype.options.icon = DefaultIcon;
import { Icon } from "ant-design-vue";
// 自定义图标
const IconFont = Icon.createFromIconfontCN({
  scriptUrl: "./iconfont/iconfont.js",
});

import { getRootTreeData, getLeafTreeData } from "@/utils/buildTreeData";
import { getChildListBatch } from "@/utils/http/bootQuery";
import { jsonsort } from "@/utils/jsonsort";
import {
  hideRightMenu,
  hideBottomPanel,
  showBottomPanel,
} from "@/utils/divResize";
import {
  getQueryLayers,
  smSpatialQuery,
  addTileSmThemeLayer,
  setQueryPermeterGeometry,
  getLayersInfo,
} from "@/utils/http/iserverQuery";

import SpatialQueryBar from "./SpatialQueryBar";
import TreeSearchResult from "./TreeSearchResult";
import axios from "axios";

export default {
  data() {
    return {
      visible: true,
      temLayerID: 0,
      expandedKeys: [],
      treedata: null,
      checkedKeys: [],
      autoExpandParent: true,
      checkedLayers: [],
      SearchDictionary: JSON.parse(localStorage.get("SearchDictionary")),
      event: {},
      selectId: null,
      selectLayerName: null,
      hackReset: true,
      isFirstLoad: true,
    };
  },
  map() {
    return this.$store.state.map;
  },
  components: {
    IconFont,
    SpatialQueryBar,
    TreeSearchResult,
  },
  computed: {
    SearchLayersNodes() {
      return this.$store.state.config.SearchLayersNodes;
    },
    defultlyers() {
      return this.$store.state.config.defultLayers;
    },
    //图层树专题图全局图层组
    treeThemeMapLayerGroup() {
      return this.$store.state.treeThemeMapLayerGroup;
    },
    //图层树空间查询结果要素组
    treeQueryFeatureGroup() {
      return this.$store.state.treeQueryFeatureGroup;
    },
    querydrawFeatureGroup() {
      return this.$store.state.querydrawFeatureGroup;
    },
    drawer() {
      return this.$store.state.drawer;
    },
    QueryBackfileds() {
      return this.$store.state.config.QueryBackfileds;
    },
  },
  mounted() {
    // 格式化图层树数据
    this.treedata = jsonsort(getRootTreeData(this.SearchLayersNodes));
    console.log("图层树构建完成：", this.treedata);

    //http://localhost:8080/?layer=公路
    var layer_index = this.getQueryString("layer");
    // console.log("this is index :" + layer_index);

    //var layer_index = "公路"

    // 设置默认展开数据
    this.defaultData(layer_index);
  },

  methods: {
    getQueryString(name) {
      if (typeof name == "string") {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        var r = window.location.search.substr(1).match(reg);
        if (window.parent !== window) {
          r = window.parent.location.search.substr(1).match(reg);
        }
        if (r != null) {
          return decodeURIComponent(r[2]);
        }
        return null;
      } else if (Array.isArray(name)) {
        console.log("----");
        var z = [];
        name.forEach(function (e, index) {
          console.log(e);
          var reg = new RegExp("(^|&)" + e + "=([^&]*)(&|$)", "i");
          var r = window.location.search.substr(1).match(reg);
          if (window.parent !== window) {
            r = window.parent.location.search.substr(1).match(reg);
          }
          if (r != null) {
            z[index] = decodeURIComponent(r[2]);
          } else z[index] = "";
        });
        return z;
      } else return null;
    },
    onClose() {
      this.visible = false;
      this.$parent.layers_btn_visiable = true;
      hideRightMenu();
    },
    onLoadData(treeNode) {
      return new Promise((resolve) => {
        if (treeNode.dataRef.children) {
          treeNode.dataRef.children = [];
          // resolve(true);
          // return;
        }
        getChildListBatch({
          params: {
            parentIds: treeNode.dataRef.id,
          },
        })
          .then((res) => {
            // 格式化图层树数据
            let data = res.data.result.records;
            treeNode.dataRef.children = jsonsort(getLeafTreeData(data));
            // 更新图层树数据
            this.treedata = [...this.treedata];
            console.log("图层树构建完成：", this.treedata);
            resolve(true);
          })
          .catch((err) => {
            console.error(err);
          });
      });
    },
    async setVectorlayertype(layer) {
      // for (let i = 0; i < layers.length; i++) {
      if (layer.legendinfo != undefined) {
        return layer;
      }
      if (layer.mapUrl && layer.mapUrl !== "") {
        let layersinfo = await getLayersInfo(layer);
        let lastChildLayer = layersinfo[layersinfo.length - 1];
        // console.log("supermap maplayer type", lastChildLayer.type);
        // lastChildLayer.type == "WMS"
        //   ? (layer.type = "WMS")
        //   : (layer.type = "UGC");
        this.setQueryBackfileds(layer);
        // if (lastChildLayer.type != "UGC") {
        //   layer.legendinfo = [];
        //   return layer;
        // }
        layer.vectortype = lastChildLayer.datasetInfo.type;
        //console.log("layerinfo", layersinfo);
        layer.legendinfo = [];
        for (let j = 0; j < layersinfo.length; j++) {
          let item = layersinfo[j];
          if (
            item["CLASS_NAME"] != "SuperMap.ServerTheme" &&
            item.caption.indexOf("世界范围") < 0
          ) {
            layer.legendinfo.push({
              maxScale: item.maxScale,
              minScale: item.minScale,
              legendurl: `${layer.mapUrl}/layers/${item.name.replace(
                "#",
                "."
              )}@@${layersinfo.mapname}/legend.png?width=25&height=25`,
              name: layer.title,
              type: "severvector",
            });
          }
        }
        if (!layer.legendinfo.length) {
          console.log("layersinfo ", layersinfo);
          let theme = layersinfo.filter(
            (item) => item.theme && item.theme.type != "LABEL"
          );
          for (let i = 0; i < theme.length; i++) {
            let them = theme[i];
            let itemstheme = them.theme.items;
            for (let j = 0; j < itemstheme.length; j++) {
              let themeitem = itemstheme[j];
              let resourceType;
              let stylejson = themeitem.style;
              if (them.datasetInfo.type == "POINT") {
                resourceType = "SYMBOL" + "MARKER";
              } else if (them.datasetInfo.type == "LINE") {
                resourceType = "SYMBOL" + "LINE";
              } else {
                resourceType = "SYMBOL" + "FILL";
              }
              let resourceImageUrl;
              await axios
                .get(layer.mapUrl + "/symbol.json", {
                  //params参数必写 , 如果没有参数传{}也可以
                  params: {
                    resourceType: resourceType,
                    style: JSON.stringify(stylejson),
                    transparent: false,
                  },
                })
                .then(function (res) {
                  //console.log("专题图图例url", res.data.resourceImageUrl);
                  resourceImageUrl = res.data.resourceImageUrl;
                  layer.legendinfo.push({
                    maxScale: them.maxScale,
                    minScale: them.minScale,
                    legendurl: `${res.data.resourceImageUrl}`,
                    name: themeitem.caption,
                    type: "servertheme",
                  });
                })
                .catch(function (err) {
                  console.log(err);
                });
              console.log(`专题图图例url${(i, j)}`, resourceImageUrl);
            }
          }
        }
      }
      //   }
      return layer;
    },
    //设置查询返回字段
    setQueryBackfileds(layer) {
      layer.backFileds = null;
      let A = this.QueryBackfileds.filter(
        (item) => layer.datasource === item.datasource
      )[0];
      if (A) {
        let B = A.datasets.filter((item) => item.dataset === layer.dataset)[0];
        if (B) {
          if (B.backFileds != undefined && B.backFileds != []) {
            layer.backFileds = B.backFileds;
          }
        }
      }
    },
    onExpand(expandedKeys) {
      this.expandedKeys = expandedKeys;
      this.autoExpandParent = false;
    },
    onCheck(checkedKeys, event) {
      /* 判断是够超过五个图层 */
      this.checkedKeys = checkedKeys;
      if (this.checkedKeys.checked.length > 20) {
        this.$message.destroy();
        this.$message.warning(
          "最多只能同时选择20个图层，请先取消其他图层再选择！"
        );
        //阻止继续选中
        this.checkedKeys.checked.pop();
        return;
      }
      // 判断是否已经选择
      if (event.checked) {
        // 图层未添加则加到图层组
        // this.addThemeLayer(event.node.dataRef);
        //   console.log(event.node.dataRef);
        let self = this;
        if (event.node.dataRef.title == "湖南省实时路况") {
          let temLayer = L.tileLayer
            .wms(event.node.dataRef.mapUrl, {
              layers: "hunan_traffic_group",
              format: "image/png",
              transparent: true,
              noWrap: true,
            })
            .addTo(this.treeThemeMapLayerGroup)
            .setZIndex(5);
          this.temLayerID = this.treeThemeMapLayerGroup.getLayerId(temLayer);
          event.node.dataRef.legendinfo = [];
          let dataref = event.node.dataRef;
          dataref.vectortype = "";
          dataref.backFileds = [];
          this.checkedLayers.push({
            key: dataref.key,
            title: dataref.title,
            nodeLayerId: this.temLayerID,
            mapUrl: dataref.mapUrl,
            legendinfo: dataref.legendinfo,
            vectortype: dataref.vectortype,
            backFileds: dataref.backFileds,
          });
        } else {
          this.setVectorlayertype(event.node.dataRef).then((data) => {
            self.addThemeLayer(data);
          });
        }
      } else {
        // 图层已添加则移除
        this.checkedLayers = this.checkedLayers.filter((item) => {
          if (item.key == event.node.dataRef.id) {
            if (event.node.dataRef.title == "湖南省实时路况") {
              this.treeThemeMapLayerGroup.removeLayer(this.temLayerID);
            } else {
              this.treeThemeMapLayerGroup.removeLayer(item.nodeLayerId);
            }
            console.log(`图层:[${item.title}] 移除成功`);
          } else {
            return item;
          }
        });
      }
      //checkedLayer变化后同步到vuex
      this.$store.commit("setCheckedLayers", this.checkedLayers);
    },
    async addThemeLayer(dataref) {
      let nodeLayerId = await addTileSmThemeLayer(
        this.treeThemeMapLayerGroup,
        dataref
      );

      if (nodeLayerId === null) {
        this.$message.warning("地图服务错误，请联系管理员");
        return;
      }

      this.checkedLayers.push({
        key: dataref.key,
        title: dataref.title,
        nodeLayerId: nodeLayerId,
        mapUrl: dataref.mapUrl,
        legendinfo: dataref.legendinfo,
        vectortype: dataref.vectortype,
        backFileds: dataref.backFileds,
      });
    },
    async query() {
      //返回绘制完成事件
      this.event = await this.$refs.SpatialQueryBar.drawerCreated();
      console.log(" this.event", this.event);
      let bufferGeometry;
      if (this.event.layerType == "polyline") {
        let _latlngs = this.event.layer._latlngs;
        let buffer_points = [];
        for (let latlng of _latlngs) {
          buffer_points.push([latlng.lng, latlng.lat]);
        }

        const bufferGeojson = buffer(
          lineString(buffer_points),
          this.$refs.SpatialQueryBar.value * 0.001,
          { units: "kilometers" }
        );
        const bufferLayer = L.geoJSON(bufferGeojson);
        bufferLayer.addTo(this.querydrawFeatureGroup);
        bufferGeometry = bufferLayer.getLayers()[0];
      }
      if (this.event.layerType !== "circlemarker") {
        this.event.layer.addTo(this.querydrawFeatureGroup);
      }

      this.$refs.TreeSearchResult.visible = true;
      this.$refs.TreeSearchResult.loading = true;
      showBottomPanel();
      //返回获取可查询图层
      let quretResultRecordsets = [];
      console.group("开始获取选中图层的可查询子图层名称");
      for (let checkedLayer of this.checkedLayers) {
        if (checkedLayer.title == "湖南省实时路况") {
          continue;
        } else {
          let queryableLayers = await getQueryLayers(checkedLayer.mapUrl);
          let backFileds = checkedLayer.backFileds;
          console.log("backfileds", backFileds);
          let param = setQueryPermeterGeometry(
            queryableLayers,
            this.event,
            null,
            backFileds,
            bufferGeometry
          );
          let recordsets = await smSpatialQuery(
            param,
            this.event.layerType,
            checkedLayer.mapUrl
          );

          // recordsets[0] 表示只取第一个可查询图层
          if (recordsets[0].features.features.length > 0) {
            quretResultRecordsets.push({
              key: checkedLayer.title,
              recordsets: recordsets,
              queryableLayers: queryableLayers,
              mapUrl: checkedLayer.mapUrl,
            });
          }
        }
      }
      console.log("查询所有选中专题图可查询图层获取完成");
      console.log("所有选中专题图空间查询完成");
      console.groupEnd();

      if (quretResultRecordsets.length > 0) {
        //构建搜索结果面板数据
        this.$refs.TreeSearchResult.buildResultData(quretResultRecordsets);
        this.$refs.TreeSearchResult.visible = true;
      } else {
        //处理没有查询到结果
        this.$refs.TreeSearchResult.visible = false;
        hideBottomPanel();
        this.$message.destroy();
        this.$message.warning(
          "当前已勾选图层没有查询到数据，请放大地图或检查绘制的查询范围！"
        );
      }
    },
    clearALLChecked() {
      this.hackReset = false; //销毁组件
      this.checkedKeys = [];
      this.checkedLayers = [];
      this.autoExpandParent = true;
      this.treedata = [...this.treedata];
      this.expandedKeys = [];
      this.$nextTick(() => {
        this.hackReset = true; //重建组件
      });
    },

    onLoadnode(key, obj) {
      //判断是否第一次加载
      if (!this.isFirstLoad || this.layer_index == null) {
        return;
      }
      let node = obj.node;
      if (this.layerIndexI < this.defultlyer.layerIndex.length) {
        let index = this.defultlyer.layerIndex[this.layerIndexI] - 1;
        let key = node.dataRef.children[index].key;
        //循环加载下一层级
        this.expandedKeys.push(key);
        //this.layerIndexI 记录循环中树的层级
        this.layerIndexI++;
        let self = this;
        //循环到最后一级，加载图层
        if (this.layerIndexI == this.defultlyer.layerIndex.length) {
          index = this.defultlyer.layerIndex[this.layerIndexI - 1] - 1;
          console.log("第一次默认打开的节点", node.dataRef.children[index].key);
          this.checkedKeys = [node.dataRef.children[index].key];
          this.setVectorlayertype(node.dataRef.children[index]).then((data) => {
            self.addThemeLayer(data);
            self.$store.commit("setCheckedLayers", this.checkedLayers);
          });
        }
      } else {
        this.isFirstLoad = false;
      }
    },
    defaultData(layer_index) {
      this.layer_index = layer_index;
      if (this.layer_index == null) {
        console.log("默认不展开");
        return;
      } else {
        this.defultlyer = this.defultlyers.filter(
          (item) =>
            this.layer_index == item.name || this.layer_index == item.alias
        )[0];
        if (this.defultlyer) {
          let defultkeys = this.treedata[this.defultlyer.layerIndex[0] - 1].key;
          this.expandedKeys = [defultkeys];
          this.layerIndexI = 1;
        } else {
          this.$message.info("未发现默认加载图层");
          this.isFirstLoad = false;
        }
      }
    },
  },
};
</script>
<style lang="less">
.number-popup-panel {
  padding: 3px;
  background-color: rgba(236, 67, 16, 0.9);
  color: #fff;

  .number-popup-panel-title {
    font-size: 12px;
    font-weight: bold;
  }

  .number-popup-panel-cell {
    font-size: 12px;
  }
}
</style>
<style lang="less" scoped>
.layerstree {
  position: absolute;
  top: 100px;
  right: 3px;
  left: 0px;
  bottom: 10px;
  padding-left: 24px;
  overflow-y: scroll;
  border-top: 1px solid #d9d9d9;
}

// 强制改变默认样式
/deep/ .ant-tree-switcher-noop {
  display: none !important;
}

/deep/.ant-tree-treenode-switcher-close {
  margin-left: 10px !important;
}

/deep/.ant-tree-treenode-switcher-close::before {
  left: 10px !important;
  border-left: 1px solid #d9d9d9;
}

.SpatialQueryBar {
  height: 40px;
  position: absolute;
  top: 60px;
  text-align: center;
  margin-left: -10px;
  padding: 0;
}

.layerstree::-webkit-scrollbar {
  /*滚动条整体样式*/
  width: 5px;
  /*高宽分别对应横竖滚动条的尺寸*/
  height: 1px;
}

.layerstree::-webkit-scrollbar-thumb {
  /*滚动条里面小方块*/
  border-radius: 5px;
  box-shadow: inset 0 0 5px @themeBackgroundColor;
  background: @themeBackgroundColor;
}

.layerstree::-webkit-scrollbar-track {
  /*滚动条里面轨道*/
  box-shadow: inset 0 0 5px @themeBackgroundColor;
  border-radius: 5px;
  background: #ededed;
}
</style>
